package com.ruoyi.appversion.service.impl;

import com.ruoyi.appversion.domain.VersionEntity;
import com.ruoyi.appversion.mapper.AppVersionMapper;
import com.ruoyi.appversion.service.AppVersionService;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

@Service
@Slf4j
public class AppVersionServiceImpl implements AppVersionService {
    @Value("${ruoyi.apkUrl}")
    private String appUrl;

    @Autowired
    private AppVersionMapper versionMapper;

    @Value("${ruoyi.profile}")
    private String profile;

    @Override
    public VersionEntity uploadApk(String versionNum, MultipartFile file, String devOrMaster) throws IOException {
        // 返回apk上传的路径，将该路径通过nginx发布
        VersionEntity selectVersion = versionMapper.selectVersion(versionNum);
        if(selectVersion != null){
            // 文件已存在，覆盖
            FileUtils.deleteFile(selectVersion.getApkPath().replace("/profile", profile));
            String uploadPath = FileUploadUtils.uploadFile(RuoYiConfig.getAppPath(), file);
            uploadPath = uploadPath.replace("/upload/","/");
            selectVersion.setApkPath(uploadPath).setDevOrMaster(devOrMaster);
            versionMapper.updateVersion(selectVersion);
            return versionMapper.selectVersion(versionNum);
        }else {
            // /upload/app/2023/11/29/a7378dc9-6af4-4235-981e-7edc32aa14cc__original.apk
            String uploadPath = FileUploadUtils.uploadFile(RuoYiConfig.getAppPath(), file);
            uploadPath = uploadPath.replace("/upload/","/");
            VersionEntity version = new VersionEntity();
            version.setVersionNum(versionNum).setApkPath(uploadPath).setDevOrMaster(devOrMaster);
            if (versionMapper.insertVersion(version) == 1){
                return versionMapper.selectVersion(versionNum);
            } else {
                return null;
            }
        }
    }

    @Override
    public String versionCheck(String versionNum) {
        VersionEntity entity = versionMapper.selectVersion(versionNum);
        List<String> versionList = versionMapper.selectVersionList(entity.getDevOrMaster());
        String latestVersion = getLatestVersion(versionList);
        int versionNow = version2Num(versionNum);
        int versionLatest = version2Num(latestVersion);
        if (versionNow < versionLatest){
            return latestVersion;
        } else {
            return "null";
        }
    }

    @Override
    public String getApkPath(String versionNum) {
        VersionEntity version = versionMapper.selectVersion(versionNum);
        return version.getApkPath().replace("/profile", appUrl);
    }

    private String getLatestVersion(List<String> versionList){
        List<Integer> list = new ArrayList<>();
        for (String s: versionList){
            list.add(version2Num(s));
        }
        Comparator<Integer> reverseComparator = Collections.reverseOrder();
        list.sort(reverseComparator);
        String s = list.get(0).toString();
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(s);
        if (s.length() == 3){
            stringBuilder.insert(1,".");
            stringBuilder.insert(3,".");
        } else if (s.length() == 2){
            stringBuilder.insert(0, "0.");
            stringBuilder.insert(3, ".");
        } else {
            stringBuilder.insert(0, "0.0.");
        }
        return stringBuilder.toString();
    }

    private int version2Num(String versionNum){
        String[] split = versionNum.split("\\.");
        return 100 * Integer.parseInt(split[0]) + 10 * Integer.parseInt(split[1]) + Integer.parseInt(split[2]);
    }
}
